home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / book / Chap04 / Triangle / Triangle.c next >
Encoding:
C/C++ Source or Header  |  1999-08-10  |  5.2 KB  |  247 lines

  1. // Triangle.c
  2. // OpenGL SuperBible, Chapter 4
  3. // Demonstrates OpenGL Triangle Fans, backface culling, and depth testing
  4. // Program by Richard S. Wright Jr.
  5.  
  6. #include <windows.h>
  7. #include <gl/gl.h>
  8. #include <gl/glu.h>
  9. #include <gl/glut.h>
  10. #include <math.h>
  11.  
  12.  
  13. // Define a constant for the value of PI
  14. #define GL_PI 3.1415f
  15.  
  16. // Rotation amounts
  17. static GLfloat xRot = 0.0f;
  18. static GLfloat yRot = 0.0f;
  19.  
  20. // Flags for effects
  21. // Flags for effects
  22. BOOL bCull = FALSE;
  23. BOOL bOutline = FALSE;
  24. BOOL bDepth = FALSE;
  25.  
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // Reset flags as appropriate in response to menu selections
  28. void ProcessMenu(int value)
  29.     {
  30.     switch(value)
  31.         {
  32.         case 1:
  33.             bDepth = !bDepth;
  34.             break;
  35.  
  36.         case 2:
  37.             bCull = !bCull;
  38.             break;
  39.  
  40.         case 3:
  41.             bOutline = !bOutline;
  42.         default:
  43.             break;
  44.         }
  45.  
  46.     glutPostRedisplay();
  47.     }
  48.  
  49.  
  50. // Called to draw scene
  51. void RenderScene(void)
  52.     {
  53.     GLfloat x,y,angle;  // Storage for coordinates and angles
  54.     int iPivot = 1;        // Used to flag alternating colors
  55.  
  56.     // Clear the window and the depth buffer
  57.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  58.  
  59.     // Turn culling on if flag is set
  60.     if(bCull)
  61.         glEnable(GL_CULL_FACE);
  62.     else
  63.         glDisable(GL_CULL_FACE);
  64.  
  65.     // Enable depth testing if flag is set
  66.     if(bDepth)
  67.         glEnable(GL_DEPTH_TEST);
  68.     else
  69.         glDisable(GL_DEPTH_TEST);
  70.  
  71.     // Draw back side as a polygon only, if flag is set
  72.     if(bOutline)
  73.         glPolygonMode(GL_BACK,GL_LINE);
  74.     else
  75.         glPolygonMode(GL_BACK,GL_FILL);
  76.         
  77.  
  78.     // Save matrix state and do the rotation
  79.     glPushMatrix();
  80.     glRotatef(xRot, 1.0f, 0.0f, 0.0f);
  81.     glRotatef(yRot, 0.0f, 1.0f, 0.0f);
  82.  
  83.  
  84.     // Begin a triangle fan
  85.     glBegin(GL_TRIANGLE_FAN);
  86.  
  87.     // Pinnacle of cone is shared vertex for fan, moved up Z axis
  88.     // to produce a cone instead of a circle
  89.     glVertex3f(0.0f, 0.0f, 75.0f);
  90.     
  91.     // Loop around in a circle and specify even points along the circle
  92.     // as the vertices of the triangle fan
  93.     for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/8.0f))
  94.         {
  95.         // Calculate x and y position of the next vertex
  96.         x = 50.0f*sin(angle);
  97.         y = 50.0f*cos(angle);
  98.     
  99.         // Alternate color between red and green
  100.         if((iPivot %2) == 0)
  101.             glColor3f(0.0f, 1.0f, 0.0f);
  102.         else
  103.             glColor3f(1.0f, 0.0f, 0.0f);
  104.             
  105.         // Increment pivot to change color next time
  106.         iPivot++;
  107.  
  108.         // Specify the next vertex for the triangle fan
  109.         glVertex2f(x, y);
  110.         }
  111.  
  112.     // Done drawing fan for cone
  113.     glEnd();
  114.  
  115.  
  116.     // Begin a new triangle fan to cover the bottom
  117.     glBegin(GL_TRIANGLE_FAN);
  118.  
  119.     // Center of fan is at the origin
  120.     glVertex2f(0.0f, 0.0f);
  121.     for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/8.0f))
  122.         {
  123.         // Calculate x and y position of the next vertex
  124.         x = 50.0f*sin(angle);
  125.         y = 50.0f*cos(angle);
  126.     
  127.         // Alternate color between red and green
  128.         if((iPivot %2) == 0)
  129.             glColor3f(0.0f, 1.0f, 0.0f);
  130.         else
  131.             glColor3f(1.0f, 0.0f, 0.0f);
  132.             
  133.         // Increment pivot to change color next time
  134.         iPivot++;
  135.  
  136.         // Specify the next vertex for the triangle fan
  137.         glVertex2f(x, y);
  138.         }
  139.  
  140.     // Done drawing the fan that covers the bottom
  141.     glEnd();
  142.  
  143.     // Restore transformations
  144.     glPopMatrix();
  145.  
  146.  
  147.     // Flush drawing commands
  148.     glutSwapBuffers();
  149.     }
  150.  
  151. // This function does any needed initialization on the rendering
  152. // context. 
  153. void SetupRC()
  154.     {
  155.     // Black background
  156.     glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
  157.  
  158.     // Set drawing color to green
  159.     glColor3f(0.0f, 1.0f, 0.0f);
  160.  
  161.     // Set color shading model to flat
  162.     glShadeModel(GL_FLAT);
  163.  
  164.     // Clock wise wound polygons are front facing, this is reversed
  165.     // because we are using triangle fans
  166.     glFrontFace(GL_CW);
  167.     }
  168.  
  169. void SpecialKeys(int key, int x, int y)
  170.     {
  171.     if(key == GLUT_KEY_UP)
  172.         xRot-= 5.0f;
  173.  
  174.     if(key == GLUT_KEY_DOWN)
  175.         xRot += 5.0f;
  176.  
  177.     if(key == GLUT_KEY_LEFT)
  178.         yRot -= 5.0f;
  179.  
  180.     if(key == GLUT_KEY_RIGHT)
  181.         yRot += 5.0f;
  182.  
  183.     if(key > 356.0f)
  184.         xRot = 0.0f;
  185.  
  186.     if(key < -1.0f)
  187.         xRot = 355.0f;
  188.  
  189.     if(key > 356.0f)
  190.         yRot = 0.0f;
  191.  
  192.     if(key < -1.0f)
  193.         yRot = 355.0f;
  194.  
  195.     // Refresh the Window
  196.     glutPostRedisplay();
  197.     }
  198.  
  199.  
  200. void ChangeSize(int w, int h)
  201.     {
  202.     GLfloat nRange = 100.0f;
  203.  
  204.     // Prevent a divide by zero
  205.     if(h == 0)
  206.         h = 1;
  207.  
  208.     // Set Viewport to window dimensions
  209.     glViewport(0, 0, w, h);
  210.  
  211.     // Reset projection matrix stack
  212.     glMatrixMode(GL_PROJECTION);
  213.     glLoadIdentity();
  214.  
  215.     // Establish clipping volume (left, right, bottom, top, near, far)
  216.     if (w <= h) 
  217.         glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
  218.     else 
  219.         glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
  220.  
  221.     // Reset Model view matrix stack
  222.     glMatrixMode(GL_MODELVIEW);
  223.     glLoadIdentity();
  224.     }
  225.  
  226. int main(int argc, char* argv[])
  227.     {
  228.     glutInit(&argc, argv);
  229.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  230.     glutCreateWindow("Triangle Culling Example");
  231.     
  232.     // Create the Menu
  233.     glutCreateMenu(ProcessMenu);
  234.     glutAddMenuEntry("Toggle depth test",1);
  235.     glutAddMenuEntry("Toggle cull backface",2);
  236.     glutAddMenuEntry("Toggle outline back",3);
  237.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  238.     
  239.     glutReshapeFunc(ChangeSize);
  240.     glutSpecialFunc(SpecialKeys);
  241.     glutDisplayFunc(RenderScene);
  242.     SetupRC();
  243.     glutMainLoop();
  244.  
  245.     return 0;
  246.     }
  247.